package com.dycong.common.reflect.Reflect;


import com.dycong.common.common.ExcelUtils;
import com.dycong.common.reflect.Reflect.fruits.Apple;
import lombok.extern.log4j.Log4j2;
import org.apache.log4j.Logger;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by ${dycong} on 2016/12/9.
 */
public class CommandUtil {

    // 給定Map物件及要產生的Bean類別名稱
    // 可以取回已經設定完成的物件
    private static Logger log = Logger.getLogger(ExcelUtils.class);

    public static Object map2Object(Map requestMap, String commandClass){
        return getCommand(requestMap, commandClass,null);
    }

    public static Object map2Object(Map requestMap, String commandClass,String datePattern){
        return getCommand(requestMap, commandClass,datePattern);
    }

    public static Object getCommand(Map requestMap,
                                    String commandClass,String datePattern) {
        Object object;
        try {
            Class c = Class.forName(commandClass);
            Object o = c.newInstance();
            object = updateCommand(requestMap, o, datePattern);
        }catch (ClassNotFoundException cnfe){
            throw new RuntimeException("ClassNotFoundException: 'commandClass'");
        }catch (InstantiationException ie){
            throw new RuntimeException("InstantiationException: 'commandClass'实例化异常");
        }catch (IllegalAccessException q){
            throw new RuntimeException("IllegalAccessException: 'commandClass'设值过程中异常");
        }catch (InvocationTargetException d){
            throw new RuntimeException("InvocationTargetException: 'commandClass'设值过程中异常");
        }
        return object;
    }

    public static Object updateCommand(Map requestMap, Object command,String datePattern) throws IllegalAccessException, IllegalArgumentException,
            InvocationTargetException {
        Method[] methods = command.getClass().getDeclaredMethods();

        for (Method method : methods) {
            // 略過private、protected成員
            // 且找出必須是set開頭的方法名稱
            if (!Modifier.isPrivate(method.getModifiers()) && !Modifier.isProtected(method.getModifiers()) && method.getName().startsWith("set")) {
                // 取得不包括set的名稱
                String tmpName = method.getName().substring(3);
                String methodName = tmpName.substring(0, 1).toLowerCase() + tmpName.substring(1);
                //String methodName=tmpName.toUpperCase().charAt(0)+tmpName.substring(1);
                // 如果setter名稱與鍵值相同
                // 呼叫對應的setter並設定值
                if (requestMap.containsKey(methodName)) {
                    String param = (String) requestMap.get(methodName);
                    Object[] values = findOutParamValues(param, method,datePattern);
                    method.invoke(command,values);
                }
            }
        }


        return command;
    }

    private static Object[] findOutParamValues(String param, Method method,String datePattern) {
        Class[] params = method.getParameterTypes();
        Object[] objs = new Object[params.length];
        for (Class parameter : params) {
            int i = 0;
            if (parameter == String.class) {
                objs[i] = param;
            } else if (parameter == Short.class) {
                short number = Short.parseShort(param);
                objs[i] = new Short(number);
            } else if (parameter == Integer.class) {
                int number = Integer.parseInt(param);
                objs[i] = new Integer(number);
            } else if (parameter == Long.class) {
                long number = Long.parseLong(param);
                objs[i] = Long.parseLong(param);
            } else if (parameter == Float.class) {
                float number = Float.parseFloat(param);
                objs[i] = new Float(number);
            } else if (params[i] == Double.class) {
                double number = Double.parseDouble(param);
                objs[i] = new Double(number);
            } else if (params[i] == Boolean.class) {
                boolean bool = Boolean.parseBoolean(param);
                objs[i] = new Boolean(bool);
            }else if (params[i] == Date.class){
                if (null==datePattern){
                    throw new RuntimeException("参数中有Date类型，但'datePattern'为'null'");
                }
                SimpleDateFormat simpleDateFormat=new SimpleDateFormat(datePattern);
                try {
                    Date date=simpleDateFormat.parse(param);
                }catch (ParseException pe){
                    log.error("日期转换异常",pe);
                }
            }
            i++;
        }
        return objs;
    }

    public static void main(String[] args) throws Exception {
        Map<String, String> request =
                new HashMap<String, String>();
        request.put("name", "caterpillar");
        request.put("color", "90");
        Object obj = CommandUtil.map2Object(request, Apple.class.getName());
        System.out.println(obj.toString());
    }


}
